//
//  ViewController.m
//  03-23LockDemo
//
//  Created by student on 16/3/23.
//  Copyright © 2016年 niit. All rights reserved.
//

#import "ViewController.h"


@interface ViewController ()
@property(nonatomic,assign)int tickets;
@property(nonatomic,assign)int cheese;
@property(nonatomic,assign)float mouse1Cheese;
@property(nonatomic,assign)float mouse2Cheese;
@property(nonatomic,assign)float mouse3Cheese;
@property(nonatomic,strong)NSLock *lock;//同步锁
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
//1.  卖票Demo
    //100张票
    //3个售票员
//    self.lock = [[NSLock alloc]init];
//    self.tickets = 100;
//    
//    NSThread *sellerThread1 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket:) object:@"售票员(张三)"];
//    
//    NSThread *sellerThread2 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket:) object:@"售票员(李四)"];
//    NSThread *sellerThread3 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket:) object:@"售票员(王五)"];
    
//    NSThread *sellerThread1 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket2) object:@"售票员(张三)"];
//    NSThread *sellerThread2 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket2) object:@"售票员(李四)"];
//    NSThread *sellerThread3 = [[NSThread alloc]initWithTarget:self selector:@selector(sellTicket2) object:@"售票员(王五)"];
//    [sellerThread1 start];
//    [sellerThread2 start];
//    [sellerThread3 start];
    
    
    
    
//   2.老鼠吃奶酪
    self.mouse1Cheese=10;
     self.mouse2Cheese=10;
     self.mouse3Cheese=10;
    self.lock=[[NSLock alloc]init];
    self.cheese=100;
    
    NSThread *carryThread1=[[NSThread alloc]initWithTarget:self selector:@selector(carryCheese:) object:@"老鼠1"];
    NSThread *carryThread2=[[NSThread alloc]initWithTarget:self selector:@selector(carryCheese:) object:@"老鼠2"];
    NSThread *carryThread3=[[NSThread alloc]initWithTarget:self selector:@selector(carryCheese:) object:@"老鼠3"];

    [carryThread1 start];
    [carryThread2 start];
    [carryThread3 start];
   
}

-(void)sellTicket:(NSString *)name
{
    [NSThread currentThread].name=name;
    while (1) {
        NSLog(@"%@ 准备卖票",name);
        NSDate *d1 = [NSDate date];
        @synchronized(self) {// 这里面的代码互斥，只有一个线程在运行里面的代码，其他线程运行到这里发现锁住的，会在这里等待
            NSDate *d2=[NSDate date];
            NSTimeInterval t =[d2 timeIntervalSinceDate:d1];
            NSLog(@"%@等待了:%.3f秒",name,t);
            //得到当前的余票
            int count = self.tickets;
            if (count>0) {
                [NSThread sleepForTimeInterval:0.01];
                self.tickets--;
                NSLog(@"%@:卖出一张票,剩余%i",name,self.tickets);
            }
            else
            {
                NSLog(@"票卖光了");
                [NSThread exit];//线程退出
            }
        }
    }
}


#pragma mark - 方式2 NSLock
// 1 卖票 锁住
// 2 喝口水 不要锁住
// 3 上个厕所 不要锁住
// 4 查询别人是不是正在卖票,如果别人不在买票,你就锁住然后卖票然后解锁,如果别人正在卖票,那你也不要闲着，看看报纸，待会再来查询一下

//优点
//1. 将必须锁住的部分代码锁住,不必须的不锁
//2. 如果发现已被锁住,可以执行其他的代码,而不是等待
-(void)sellTicket2
{
    while (1) {
        
        if ([self.lock tryLock]) {//尝试去锁住
            //说明没人加锁，那我就锁住,开始卖票
            //得到当前的余票
            int count = self.tickets;
            if (count>0) {
                [NSThread sleepForTimeInterval:0.01];
                self.tickets--;
                [self.lock unlock];
                NSLog(@"%@:卖出一张票,剩余%i",[NSThread currentThread].name,self.tickets);
                
                NSLog(@"%@:喝口水休息下!",[NSThread currentThread].name);
                [NSThread sleepForTimeInterval:0.01];
            }
            else
            {
                NSLog(@"%@:票卖光了",[NSThread currentThread].name);
                [self.lock unlock];
                [NSThread exit];//线程退出
            }
            
        }
        else
        {
            //没能锁住,说明别人已锁住,那我先干点别的事
            NSLog(@"%@:有人正在卖票，我先看会儿报纸，等一会儿",[NSThread currentThread].name);
            [NSThread sleepForTimeInterval:0.01];
        }
        
        
    }
    
}


#pragma MARK -练习（老鼠吃奶酪）
// 练习:
// 一个盒子里有100块奶酪,有个鼠洞通到盒子
// 3只老鼠,老鼠需要把奶酪叼回自己的窝里，每只老鼠搬得速度不同。(起始的时候，每只老鼠窝里有10块奶酪)
// 鼠洞很小，每一刻只能有一只老鼠在里面通行。（搬奶酪过程，线程互斥）
// 每只老鼠跑动速度不同(来回搬一次时间为0.3s 0.4s 0.5s   )
// 每只老鼠搬完了要休息(0.2s)
// 老鼠发现如果不能叼奶酪，就是在窝里吃0.1块奶酪(耗费每0.1秒),然后继续尝试能不能叼
// 显示最后3只老鼠窝里的奶酪数量，如果没得吃，那只老鼠饿死。
// 线程结束条件:盒子里奶酪没了,或者饿死了。
-(void)carryCheese:(NSString *)name
{
    while (1) {
        [NSThread currentThread].name=name;
        if ([self.lock tryLock]) {
            NSLog(@"%@:去搬奶酪",name);
            int count=self.cheese;
            if (count>0) {
                if ([name isEqualToString:@"老鼠1"]) {
                    [NSThread sleepForTimeInterval:0.3];
                    self.mouse1Cheese++;
                    NSLog(@"%@ : 窝里一共有%.1f块奶酪",name,self.mouse1Cheese);
                }
                else if ([name isEqualToString:@"老鼠2"]) {
                    [NSThread sleepForTimeInterval:0.4];
                    self.mouse2Cheese++;
                    NSLog(@"%@ : 窝里一共有%.1f块奶酪",name,self.mouse2Cheese);
                }
                else if ([name isEqualToString:@"老鼠3"]) {
                    [NSThread sleepForTimeInterval:0.5];
                    self.mouse3Cheese++;
                    NSLog(@"%@ : 窝里一共有%.1f块奶酪",name,self.mouse3Cheese);
                }
                self.cheese--;
                NSLog(@"盒子里还剩%i块奶酪",self.cheese);
                
                [self.lock unlock];
                NSLog(@"%@:搬完奶酪休息一下,2s钟",name);
                [NSThread sleepForTimeInterval:0.2];
            }
            else{
                NSLog(@"%@:奶酪没了",name);
                [self.lock unlock];
                
                [NSThread exit];
              
            }
        }
        else{
            
            if ([name isEqualToString:@"老鼠1"]) {
                if (self.mouse1Cheese<=0) {
                    NSLog(@"%@:奶酪吃完,线程结束",name);
                    [NSThread exit];
                }
                else{
                    NSLog(@"%@:有人正在搬运奶酪,我先吃点奶酪",name);
                    [NSThread sleepForTimeInterval:0.1];
                    self.mouse1Cheese=self.mouse1Cheese-0.1;
                    NSLog(@"%@ : 窝里一共有%.1f块奶酪",name,self.mouse1Cheese);
                }
                
            }
            else if ([name isEqualToString:@"老鼠2"]) {
                if (self.mouse2Cheese<=0) {
                    NSLog(@"%@:奶酪吃完,线程结束",name);
                    
                    [NSThread exit];
                }
                else{
                    NSLog(@"%@:有人正在搬运奶酪,我先吃点奶酪",name);
                    [NSThread sleepForTimeInterval:0.1];
                    self.mouse2Cheese=self.mouse2Cheese-0.1;
                    NSLog(@"%@ : 窝里一共有%.1f块奶酪",name,self.mouse2Cheese);
                }
            }
            else if ([name isEqualToString:@"老鼠3"]) {
                if (self.mouse3Cheese<=0) {
                    NSLog(@"%@:奶酪吃完,线程结束",name);
                    
                    [NSThread exit];
                }
                else{
                    NSLog(@"%@:有人正在搬运奶酪,我先吃点奶酪",name);
                    [NSThread sleepForTimeInterval:0.1];
                    self.mouse3Cheese=self.mouse3Cheese-0.1;
                    NSLog(@"%@ : 窝里一共有%.1f块奶酪",name,self.mouse3Cheese);
                }
            }
        }
    }
 
}

@end
